package cn.juque.luceneplus.constants;

import cn.hutool.core.collection.CollUtil;
import java.util.List;
import org.apache.lucene.document.DoublePoint;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.SortedDocValuesField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.NumericUtils;

/**
 * @author nuoka
 * @version 1.0.0
 * <li>IntelliJ IDEA</li>
 * <li></li>
 * @date 2021/10/4 0:23
 **/
public enum FieldTypeEnum {
    /**
     * enum
     */
    STRING("String", String.class),
    INTEGER("Integer", Integer.class),
    LONG("Long", Long.class),
    DOUBLE("Double", Double.class),
    TEXT("Text", String.class);

    /**
     * 类型
     */
    private String type;

    /**
     * 对应java类
     */
    private Class<?> javaClazz;

    FieldTypeEnum(String type, Class<?> javaClazz) {
        this.type = type;
        this.javaClazz = javaClazz;
    }

    public String getType() {
        return type;
    }

    public static List<Field> forField(String fieldName, Object value, FieldTypeEnum typeEnum, Store store,
        Boolean isPoint, Boolean isSort) {
        List<Field> fieldList = CollUtil.newArrayList();
        switch (typeEnum) {
            case LONG:
                if (Boolean.TRUE.equals(isPoint)) {
                    fieldList.add(new LongPoint(fieldName, Long.parseLong(value.toString())));
                }
                if (Store.YES.equals(store)) {
                    fieldList.add(new StoredField(fieldName, Long.parseLong(value.toString())));
                }
                if(Boolean.TRUE.equals(isSort)) {
                    fieldList.add(new NumericDocValuesField(fieldName, Long.parseLong(value.toString())));
                }
                break;
            case DOUBLE:
                if (Boolean.TRUE.equals(isPoint)) {
                    fieldList.add(new DoublePoint(fieldName, Double.parseDouble(value.toString())));
                }
                if (Store.YES.equals(store)) {
                    fieldList.add(new StoredField(fieldName, Double.parseDouble(value.toString())));
                }
                if(Boolean.TRUE.equals(isSort)) {
                    fieldList.add(new NumericDocValuesField(fieldName, NumericUtils.doubleToSortableLong(Double.parseDouble(value.toString()))));
                }
                break;
            case INTEGER:
                if (Boolean.TRUE.equals(isPoint)) {
                    fieldList.add(new IntPoint(fieldName, Integer.parseInt(value.toString())));
                }
                if (Store.YES.equals(store)) {
                    fieldList.add(new StoredField(fieldName, Integer.parseInt(value.toString())));
                }
                if(Boolean.TRUE.equals(isSort)) {
                    fieldList.add(new NumericDocValuesField(fieldName, Integer.parseInt(value.toString())));
                }
                break;
            case TEXT:
                fieldList.add(new TextField(fieldName, value.toString(), store));
                break;
            default:
                fieldList.add(new StringField(fieldName, value.toString(), store));
                if(Boolean.TRUE.equals(isSort)) {
                    fieldList.add(new SortedDocValuesField(fieldName, new BytesRef(value.toString())));
                }
                break;
        }

        return fieldList;
    }

    public static FieldTypeEnum forName(String type) {
        for (FieldTypeEnum typeEnum : FieldTypeEnum.values()) {
            if (typeEnum.type.equals(type)) {
                return typeEnum;
            }
        }
        return STRING;
    }
}
